home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Ultimate Window Set -…Games & Quality Programs
/
The Ultimate Window Set - 250 Games & Quality Programs.iso
/
win
/
pro248
/
writepcx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-21
|
23KB
|
474 lines
/************************************************************************\
* *
* writepcx.c *
* *
* This file is part of PICTURE MAN image file converter/processor *
* *
* 1992 Potapov WORKS, STOIK Ltd. *
* *
* This file contains source code for PCX file writer *
* *
* Compiler: MS C v.6.00A *
* *
* You may use, modify and distribute this code freely *
* *
\************************************************************************/
#include <windows.h>
#include "custconv.h"
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define BUFSIZE 4096
typedef struct {
char manuf; /* Always =10 for Paintbrush */
char hard; /* Version information */
char encod; /* Run-length encoding (=1) */
char bitpx; /* Bits per pixel */
unsigned x1; /* Picture dimensions (incl) */
unsigned y1;
unsigned x2;
unsigned y2;
unsigned hres; /* Display horiz resolution */
unsigned vres; /* Display vert resolution */
char clrma[48]; /* Pallete */
char vmode; /* (ignored) */
char nplanes; /* Number of planes (ver 2.5=0)*/
unsigned bplin; /* Bytes per line */
unsigned palinfo; /* Palette Info (1=col, 2=gray)*/
unsigned shres; /* Scanner resolution */
unsigned svres; /* */
char xtra[54]; /* Extra space (filler) */
} PCXhdr;
typedef struct{
int file;
BOOL PCXpalette;
PAL pal;
BYTE buffer[BUFSIZE];
WORD pos;
PCXhdr hdr;
}PCXStruct;
/************************************************************************\
* *
* ROUTINE: int FAR PASCAL LibMain(HANDLE hModule, WORD wDataSeg, *
* WORD cbHeapSize, LPSTR lpszCmdLine) *
* PURPOSE: DLL entry point. *
* *
\************************************************************************/
int FAR PASCAL LibMain(HANDLE hModule, WORD wDataSeg,
WORD cbHeapSize, LPSTR lpszCmdLine)
{
return 1;
}
/************************************************************************\
* *
* ROUTINE: int FAR PASCAL WEP(int bSystemExit) *
* *
* PURPOSE: DLL exit procedure *
* *
\************************************************************************/
int FAR PASCAL WEP(int bSystemExit)
{
return 1;
}
/************************************************************************\
* *
* ROUTINE: WORD FAR PASCAL Magic(void) *
* *
* PURPOSE: Identification routine *
* RETURNS: 'Magic number' SRC_MAGIC *
* *
\************************************************************************/
WORD FAR PASCAL Magic(void)
{
return DST_MAGIC;
}
/************************************************************************\
* *
* ROUTINE: void FAR PASCAL GetDescription(LPSTR str) *
* *
* PURPOSE: Sets format name *
* *
* PARAMETERS: LPSTR str - pointer for format name storage. The length *
* name must be less than 40! *
* *
\************************************************************************/
void FAR PASCAL GetDescription(LPSTR str)
{
lstrcpy(str,"ZSoft PaintBrush PCX");
}
/************************************************************************\
* *
* ROUTINE: void FAR PASCAL GetExtension(LPSTR str) *
* *
* PURPOSE: Sets format file extension *
* *
* PARAMETERS: LPSTR str - pointer for format file extension. *
* *
\************************************************************************/
void FAR PASCAL GetExtension(LPSTR str)
{
lstrcpy(str,"PCX");
}
/************************************************************************\
* *
* ROUTINE: DWORD FAR PASCAL GetFlags(void) *
* *
* PURPOSE: Sets flag for converter capabilities *
* *
* PARAMETERS: None *
* *
* RETURNS: Flags *
* Color info bits *
* INFO_COLOR // Image is colored *
* INFO_PALETTE // Image is paletted *
* INFO_NEGATIVE // Image is negative *
* File organization bits *
* INFO_TEMPFILE // Only using temporary file *
* INFO_COMPRESSED // Image is compressed *
* INFO_FORWARD // Up to down *
* INFO_BACKWARD // Down to up *
* INFO_RANDOM // Random access is allowed *
* Row organization bits *
* INFO_PACKED // (bps < 8) bits are shifted together *
* INFO_SEPARATE // (bps !=8) bitplanes are separated *
* *
* Bits for GetFlags() *
* Destination capabilites bits *
* INFO_1BPS // Accepts 1-bit data *
* INFO_4BPS // Accepts 4-bit data *
* INFO_8BPS // Accepts 8-bit data *
* INFO_24BPS // Accepts 24-bit data *
* INFO_GRAY // Accepts true gray data *
* INFO_STDPAL // Requires std. EGA/VGA palette *
* INFO_ANYPAL // Accepts any palette *
* Source/Destination capabilites bits *
* INFO_HASOPTIONS // Has SetOptions() *
* INFO_NOFILE // Do not open src/dst file *
* *
* ALL OTHER BITS ARE RESERVED *
* *
\************************************************************************/
DWORD FAR PASCAL GetFlags(void)
{
return ( INFO_COMPRESSED | INFO_FORWARD | INFO_1BPS | \
INFO_4BPS | INFO_8BPS | INFO_24BPS | INFO_STDPAL | INFO_ANYPAL );
}
/************************************************************************\
* *
* ROUTINE: int FAR PASCAL GetPrivateSize() *
* *
* PURPOSE: Returns size of private memory block *
* *
* *
\************************************************************************/
int FAR PASCAL GetPrivateSize()
{
return sizeof(PCXStruct);
}
/************************************************************************\
* *
* ROUTINE: int FAR PASCAL WriteHeader(LPINFO p, void far * lpPrivate)*
* *
* PURPOSE: Writes image header. *
* *
* PARAMETERS: LPINFO p - pointer to INFO structure *
* void far * lpPrivate - pointer to *
* custom structure to store private data *
* *
* RETURNS: *
* OK - Success *
* BADFORMAT - Bad signature *
* UNSUPPORTED- Unsupported subformat *
* BADFILE - Error in file structure *
* CANNOTOPEN - Cannot open src/dest *
* INTERNAL - Reserved *
* BADDLL - Error initializing DLL *
* BADREQUEST - Unsupported type of conversion *
* BADTEMPFILE- Error creating/reading tempfile *
* NOMEMORY - No enough global heap *
* NODISK - No enough disk space *
* USERABORT - Cancelled by user *
* BADPARMS - Conflicting parameters *
* *
\************************************************************************/
int FAR PASCAL WriteHeader(LPINFO p, void far *lpPrivate)
{
int i,j;
PCXStruct far * lpPCXStruct = lpPrivate;
lpPCXStruct->hdr.manuf = 10; // manuf
lpPCXStruct->hdr.hard = 5; // hard
lpPCXStruct->hdr.encod = 1; // encod
lpPCXStruct->hdr.bitpx = 1; // bitpix ***
lpPCXStruct->hdr.x1 = 0; // x1, y1
lpPCXStruct->hdr.y1 = 0;
lpPCXStruct->hdr.x2 = 0;
lpPCXStruct->hdr.y2 = 0;
lpPCXStruct->hdr.hres = 640 ;
lpPCXStruct->hdr.vres = 480;
lpPCXStruct->hdr.vmode = 0;
lpPCXStruct->hdr.nplanes = 1;
lpPCXStruct->hdr.bplin = 0;
lpPCXStruct->hdr.palinfo= 0;
lpPCXStruct->hdr.shres = 300;
lpPCXStruct->hdr.svres = 300;
lpPCXStruct->hdr.x2 = p->w - 1;
lpPCXStruct->hdr.y2 = p->h - 1;
if( p->resunit == RES_SCREEN )
{
lpPCXStruct->hdr.hres = (WORD)p->xres; lpPCXStruct->hdr.vres = (WORD)p->yres;
}
switch( p->bps )
{
case 1:
lpPCXStruct->hdr.bitpx = 1;
lpPCXStruct->hdr.nplanes = 1;
if( p->resunit != RES_SCREEN )
{
lpPCXStruct->hdr.hres = 640; lpPCXStruct->hdr.vres = 480;
}
lpPCXStruct->PCXpalette = 0;
lpPCXStruct->hdr.clrma[0] = lpPCXStruct->hdr.clrma[1] = lpPCXStruct->hdr.clrma[2] = 0;
lpPCXStruct->hdr.clrma[3] = lpPCXStruct->hdr.clrma[4] = lpPCXStruct->hdr.clrma[5] = 0xFF;
break;
case 4:
lpPCXStruct->hdr.bitpx = 1;
lpPCXStruct->hdr.nplanes = 4;
if( p->resunit != RES_SCREEN )
{
lpPCXStruct->hdr.hres = 640; lpPCXStruct->hdr.vres = 480;
}
lpPCXStruct->PCXpalette = 0;
for( i = 0; i < 16; i++ )
for( j = 0; j < 3; j++ )
lpPCXStruct->hdr.clrma[i*3+j] = p->pal[j][i];
break;
case 8:
lpPCXStruct->hdr.bitpx = 8;
lpPCXStruct->hdr.nplanes = 1;
if( p->resunit != RES_SCREEN )
{
lpPCXStruct->hdr.hres = 320; lpPCXStruct->hdr.vres = 200;
}
lpPCXStruct->PCXpalette = 1;
for( i = 0; i < 3; i++ )
for( j = 0; j < 256; j++ )
lpPCXStruct->pal[i][j] = p->pal[i][j];
break;
case 24:
lpPCXStruct->hdr.bitpx = 8;
lpPCXStruct->hdr.nplanes = 3;
if( p->resunit != RES_SCREEN )
{
lpPCXStruct->hdr.hres = 640; lpPCXStruct->hdr.vres = 480;
}
break;
}
lpPCXStruct->file = p->file;
p->nplanes = lpPCXStruct->hdr.nplanes;
p->bplin = lpPCXStruct->hdr.bplin =
(WORD)( ( (DWORD)lpPCXStruct->hdr.bitpx * (DWORD)p->w + 15lu ) / 16lu ) * 2;
p->flags |= INFO_COMPRESSED | INFO_FORWARD | INFO_1BPS | \
INFO_4BPS | INFO_8BPS | INFO_24BPS | INFO_STDPAL | INFO_ANYPAL | \
INFO_COLOR | INFO_PALETTE;
if( lpPCXStruct->hdr.bitpx != 8 ) p->flags |= INFO_PACKED;
if( lpPCXStruct->hdr.nplanes != 1 ) p->flags |= INFO_SEPARATE;
lpPCXStruct->pos = 0;
if(_lwrite( lpPCXStruct->file,(LPSTR)&(lpPCXStruct->hdr),sizeof(lpPCXStruct->hdr)) != sizeof(lpPCXStruct->hdr)) return NODISK;
return OK;
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
/* useful macros */
#define BufByte(x) ((lpPCXStruct->pos < BUFSIZE) ? ((lpPCXStruct->buffer[lpPCXStruct->pos++] = x),OK) : putbuf(x,lpPCXStruct))
/* useful subfunctions */
int putbuf(BYTE b,PCXStruct far *lpPCXStruct)
{
if( _lwrite(lpPCXStruct->file,lpPCXStruct->buffer,BUFSIZE) != BUFSIZE ) return NODISK;
lpPCXStruct->buffer[0] = b; lpPCXStruct->pos = 1;
return OK;
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
int FlushOutBuf(PCXStruct far *lpPCXStruct)
{
if( !lpPCXStruct->pos ) return OK;
return ( _lwrite(lpPCXStruct->file,lpPCXStruct->buffer,lpPCXStruct->pos) != lpPCXStruct->pos ) ? NODISK : OK;
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
static int PCXpack(LPBYTE buf, WORD len, void far *lpPrivate)
{
int PCXcount,ret;
BYTE PCXbyte;
PCXStruct far * lpPCXStruct = lpPrivate;
PCXcount = 0;
while(len)
{
if(!PCXcount)
{
PCXcount = 1;
PCXbyte = *buf++;
len --;
}
while(len && PCXcount < 0x3F && *buf == PCXbyte)
{
PCXcount++; buf++; len--;
}
if(!len) /* return OK; */ break;
if(PCXcount == 1 && (PCXbyte & 0xC0) != 0xC0 )
{
if(ret = BufByte(PCXbyte)) return ret;
}
else
{
if(ret = BufByte((BYTE)(PCXcount | 0xC0))) return ret;
if(ret = BufByte(PCXbyte)) return ret;
}
PCXcount = 0;
}
if(PCXcount)
{
if(PCXcount == 1 && (PCXbyte & 0xC0) != 0xC0 )
{
if(ret = BufByte(PCXbyte)) return ret;
}
else
{
if(ret = BufByte((BYTE)(PCXcount | 0xC0))) return ret;
if(ret = BufByte(PCXbyte)) return ret;
}
PCXcount = 0;
}
return OK;
}
/************************************************************************\
* *
* ROUTINE: int FAR PASCAL EndWrite(void far * lpPrivate) *
* void far * lpPrivate - pointer to *
* custom structure to store private data *
* *
* PURPOSE: Terminates conversion. *
* *
* RETURNS: *
* OK - Success *
* BADFORMAT - Bad signature *
* UNSUPPORTED- Unsupported subformat *
* BADFILE - Error in file structure *
* CANNOTOPEN - Cannot open src/dest *
* INTERNAL - Reserved *
* BADDLL - Error initializing DLL *
* BADREQUEST - Unsupported type of conversion *
* BADTEMPFILE- Error creating/reading tempfile *
* NOMEMORY - No enough global heap *
* NODISK - No enough disk space *
* USERABORT - Cancelled by user *
* BADPARMS - Conflicting parameters *
* *
\************************************************************************/
int FAR PASCAL EndWrite(void far *lpPrivate)
{
WORD i;
PCXStruct far * lpPCXStruct = lpPrivate;
if(lpPCXStruct->PCXpalette)
{
if(BufByte(0x0C)) return NODISK;
for(i = 0; i<256; i++)
{
if( BufByte(lpPCXStruct->pal[0][i]) ||
BufByte(lpPCXStruct->pal[1][i]) ||
BufByte(lpPCXStruct->pal[2][i]) ) return NODISK;
}
}
return FlushOutBuf(lpPCXStruct);
}
/************************************************************************\
* *
* ROUTINE: int FAR PASCAL WriteRow(int row, LPBYTE p, *
* void far * lpPrivate) *
* *
* PURPOSE: Writes image row. *
* *
* PARAMETERS: int row - the number of row to read *
* LPBYTE p - pointer to buffer to store image row *
* void far * lpPrivate - pointer to *
* custom structure to store private data *
* *
* RETURNS: *
* OK - Success *
* BADFORMAT - Bad signature *
* UNSUPPORTED- Unsupported subformat *
* BADFILE - Error in file structure *
* CANNOTOPEN - Cannot open src/dest *
* INTERNAL - Reserved *
* BADDLL - Error initializing DLL *
* BADREQUEST - Unsupported type of conversion *
* BADTEMPFILE- Error creating/reading tempfile *
* NOMEMORY - No enough global heap *
* NODISK - No enough disk space *
* USERABORT - Cancelled by user *
* BADPARMS - Conflicting parameters *
* *
\************************************************************************/
int FAR PASCAL WriteRow(int row,LPBYTE buf,void far *lpPrivate)
{
int i;
PCXStruct far *lpPCXStruct = lpPrivate;
for( i = 0; i < (int)lpPCXStruct->hdr.nplanes; i++ )
{
if( PCXpack(buf,lpPCXStruct->hdr.bplin,lpPrivate) ) return NODISK;
buf += lpPCXStruct->hdr.bplin;
}
return OK;
}
/************************************************************************\
* *
* ROUTINE: void FAR PASCAL CleanUp(void far *lpPrivate) *
* void far * lpPrivate - pointer to *
* custom structure to store private data *
* *
* PURPOSE: Frees all auxiliary buffers. *
* *
\************************************************************************/
void FAR PASCAL CleanUp(void far *lpPrivate)
{
}